package com.situ.vivamarket.service.impl;

import com.situ.vivamarket.dao.CategoryDao;
import com.situ.vivamarket.dao.GoodsDao;
import com.situ.vivamarket.model.Category;

import com.situ.vivamarket.model.Goods;
import com.situ.vivamarket.service.CategoryService;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

@Service
@CacheConfig(cacheNames = "com.situ.vivamarket.service.impl.CatServiceImpl") //名字定义在类上
public class CatServiceImpl implements CategoryService {
    private CategoryDao categoryDao;
    private GoodsDao goodsDao;
    @Autowired
    public void setCategoryDao(CategoryDao categoryDao) {
        this.categoryDao = categoryDao;
    }
    @Autowired
    public void setGoodsDao(GoodsDao goodsDao) {
        this.goodsDao = goodsDao;
    }

    @Cacheable(keyGenerator = "myKeyGenerator") //加上自定义的key生成器
    @Override
    public Category findById(Integer id) {
        return categoryDao.findById(id);
    }

    @Cacheable(keyGenerator = "myKeyGenerator")
    @Override
    public List<Category> findAll() {
        return this.categoryDao.findAll();
    }

    //    从缓存中清除
    @CacheEvict(allEntries = true)
    @Override
    public int deleteByIds(Integer[] ids) {
        List<Integer> validIds = new ArrayList<Integer>();
//        安全删除
        for (Integer id : ids) {
//            获取当前类的动态代理实例
            CategoryService cs=(CategoryService) AopContext.currentProxy();
            Category category = cs.findById(id);//利用aop缓存，要调用代理类的findById才行
            //        安全判断
            if(category==null){
                continue;
            }
            if(!CollectionUtils.isEmpty(category.getChildren())){
                throw new RuntimeException("有子类别，无法删除");
            }
//           判断这个id是否有商品
            List<Goods> goods =goodsDao.findByCatId(id,0);
            if(goods==null){
                validIds.add(id);
            }

        }
        if(validIds.isEmpty()){
            throw new RuntimeException("不存在合法的类别编号");
        }

        return  this.categoryDao.deleteByIds(validIds.toArray(new Integer[]{}));
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean add(Category category) {
        return categoryDao.insert(category) > 0;
    }

    @CacheEvict(allEntries = true)
    @Override
    public boolean update(Category category) {
        return categoryDao.update(category) > 0;
    }




    @Cacheable(keyGenerator = "myKeyGenerator")
    @Override
    public Category buildTree() {
        //返回当前实现类的代理实例
        CategoryService cs = (CategoryService) AopContext.currentProxy();
        //如此调用才能触发代理，如果直接this.findAll()，那么由于this并不是代理类实例，无法触发aop
        //另外，注意，从caffeine中获取的数据，是可变的，若修改了数据，则缓存的数据也会同步修改，下次取出就是修改后的了
        List<Category> categories = cs.findAll();
        return Category.buildCategoryTree(categories);

    }

}
